package ssau.knyazev.wavelet.core;

import ssau.knyazev.core.image.ImageModel;
import ssau.knyazev.modules.MatrixMath;


public class WaveletCore {
	
	public static float[][] getMatrixH(int size){
		float[][] H = new float[size][size];
		
		for (int i = 0; i < size/2; i++){
			H[i][(i*2) % size] = 0.25f;
			H[i][(i*2 + 1) % size] = 0.25f;
			H[i][(i*2 + 2) % size] = 0.25f;
			H[i][(i*2 + 3) % size] = 0.25f;
		}
		for (int i = size/2; i < size; i++){
			H[i][(i*2) % size] = 0.25f;
			H[i][(i*2 + 1) % size] = -0.25f;
			H[i][(i*2 + 2) % size] = 0.25f;
			H[i][(i*2 + 3) % size] = -0.25f;
		}
		
		return H;
	}
	

	
	public static float[][] getByRow(float[][] src){
		float[][] res = new float[src.length][src.length];
		float[][] H = getMatrixH(src.length);
		for (int i = 0; i < res.length; i++){
			res[i] = MatrixMath.multiplication(H, src[i]);
		}
		return res;
	}
	
	public static float[][] getByCol(float[][] src){
		float[][] res = new float[src.length][src.length];
		float[][] H = getMatrixH(src.length);
		for (int i = 0; i < res.length; i++){
			float[] vec = new float[src.length];
			for (int j = 0; j < src.length; j++){
				vec[j] = src[j][i];
			}
			vec = MatrixMath.multiplication(H, vec);
			for (int j = 0; j < src.length; j++){
				res[j][i] = vec[j]; 
			}
		}
		return res;
	}

	public static ImageModel filtration(ImageModel src, double k){
		float[][] x = MatrixMath.copyMatrix(src.getValues());
		double kq = Math.sqrt(MatrixMath.var(x));
		kq = k*kq;
		for (int i = 0; i < x.length; i++){
			for (int j = 0; j < x[i].length; j++){
				x[i][j] = (Math.abs(x[i][j]) > kq) ? 0 : x[i][j];
			}
		}
		return new ImageModel(x);
	}
	
	public static ImageModel colSumCMP(ImageModel src){
		float[][] srcMatrix = src.getValues();
		float[][] x = new float[srcMatrix.length][srcMatrix[0].length/2];
		for (int i = 0; i < x.length; i++){
			for (int j = 0; j < x[0].length; j++){
				x[i][j] = srcMatrix[i][j*2] + srcMatrix[i][j*2+1];
			}
		}
		return new ImageModel(x);
	}
	
	public static ImageModel rowSumCMP(ImageModel src){
		float[][] srcMatrix = src.getValues();
		float[][] x = new float[srcMatrix.length/2][srcMatrix[0].length];
		for (int i = 0; i < x.length; i++){
			for (int j = 0; j < x[0].length; j++){
				x[i][j] = srcMatrix[i*2][j] + srcMatrix[i*2+1][j];
			}
		}
		return new ImageModel(x);
	}
	
	public static ImageModel colDifferenceCMP(ImageModel src){
		float[][] srcMatrix = src.getValues();
		float[][] x = new float[srcMatrix.length][srcMatrix[0].length/2];
		for (int i = 0; i < x.length; i++){
			for (int j = 0; j < x[0].length; j++){
				x[i][j] = srcMatrix[i][j*2] - srcMatrix[i][j*2+1];
			}
		}
		return new ImageModel(x);
	}
	
	public static ImageModel rowDifferenceCMP(ImageModel src){
		float[][] srcMatrix = src.getValues();
		float[][] x = new float[srcMatrix.length/2][srcMatrix[0].length];
		for (int i = 0; i < x.length; i++){
			for (int j = 0; j < x[0].length; j++){
				x[i][j] = srcMatrix[i*2][j] - srcMatrix[i*2+1][j];
			}
		}
		return new ImageModel(x);
	}
	
	public static ImageModel colSumRCV(ImageModel dif, ImageModel sum){
		float[][] sumMatrix = sum.getValues();
		float[][] difMatrix = dif.getValues();
		float[][] x = new float[sumMatrix.length*2][sumMatrix[0].length];
		for (int i = 0; i < sumMatrix.length; i++){
			for (int j = 0; j < sumMatrix[0].length; j++){
				x[2*i][j] = (sumMatrix[i][j] + difMatrix[i][j])/2;
				x[2*i+1][j] = (sumMatrix[i][j] - difMatrix[i][j])/2;
			}
		}
		return new ImageModel(x);
	}
	
	public static ImageModel rowSumRCV(ImageModel dif, ImageModel sum){
		float[][] sumMatrix = sum.getValues();
		float[][] difMatrix = dif.getValues();
		float[][] x = new float[sumMatrix.length][sumMatrix[0].length*2];
		for (int i = 0; i < sumMatrix.length; i++){
			for (int j = 0; j < sumMatrix[0].length; j++){
				x[i][j*2] = (sumMatrix[i][j] + difMatrix[i][j])/2;
				x[i][j*2+1] = (sumMatrix[i][j] - difMatrix[i][j])/2;
			}
		}
		return new ImageModel(x);
	}
	
}
